<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Go by Example 中文版: JSON</title>
    <link rel=stylesheet href="site.css">
  </head>
  <script>
      onkeydown = (e) => {
          
          if (e.key == "ArrowLeft") {
              window.location.href = 'regular-expressions';
          }
          
          
          if (e.key == "ArrowRight") {
              window.location.href = 'xml';
          }
          
      }
  </script>
  <body>

    <div class="example" id="json">
      <h2><a href="./">Go by Example 中文版</a>: JSON</h2>
      
      <table>
        
        <tr>
          <td class="docs">
            <p>Go 提供内建的 JSON 编码解码（序列化反序列化）支持，
包括内建及自定义类型与 JSON 数据之间的转化。</p>

          </td>
          <td class="code empty leading">
            
          
          </td>
        </tr>
        
        <tr>
          <td class="docs">
            
          </td>
          <td class="code leading">
            <a href="http://play.golang.org/p/D9GUtTt3czB"><img title="Run code" src="play.png" class="run" /></a><img title="Copy code" src="clipboard.png" class="copy" />
          <div class="highlight"><pre><span class="kn">package</span> <span class="nx">main</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            
          </td>
          <td class="code leading">
            
          <div class="highlight"><pre><span class="kn">import</span> <span class="p">(</span>
    <span class="s">&quot;encoding/json&quot;</span>
    <span class="s">&quot;fmt&quot;</span>
    <span class="s">&quot;os&quot;</span>
<span class="p">)</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            <p>下面我们将使用这两个结构体来演示自定义类型的编码和解码。</p>

          </td>
          <td class="code leading">
            
          <div class="highlight"><pre><span class="kd">type</span> <span class="nx">response1</span> <span class="kd">struct</span> <span class="p">{</span>
    <span class="nx">Page</span>   <span class="kt">int</span>
    <span class="nx">Fruits</span> <span class="p">[]</span><span class="kt">string</span>
<span class="p">}</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            <p>只有 <code>可导出</code> 的字段才会被 JSON 编码/解码。必须以大写字母开头的字段才是可导出的。</p>

          </td>
          <td class="code leading">
            
          <div class="highlight"><pre><span class="kd">type</span> <span class="nx">response2</span> <span class="kd">struct</span> <span class="p">{</span>
    <span class="nx">Page</span>   <span class="kt">int</span>      <span class="s">`json:&quot;page&quot;`</span>
    <span class="nx">Fruits</span> <span class="p">[]</span><span class="kt">string</span> <span class="s">`json:&quot;fruits&quot;`</span>
<span class="p">}</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            
          </td>
          <td class="code leading">
            
          <div class="highlight"><pre><span class="kd">func</span> <span class="nx">main</span><span class="p">()</span> <span class="p">{</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            <p>首先我们来看一下基本数据类型到 JSON 字符串的编码过程。
这是一些原子值的例子。</p>

          </td>
          <td class="code leading">
            
          <div class="highlight"><pre>    <span class="nx">bolB</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">Marshal</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">bolB</span><span class="p">))</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            
          </td>
          <td class="code leading">
            
          <div class="highlight"><pre>    <span class="nx">intB</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">Marshal</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">intB</span><span class="p">))</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            
          </td>
          <td class="code leading">
            
          <div class="highlight"><pre>    <span class="nx">fltB</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">Marshal</span><span class="p">(</span><span class="mf">2.34</span><span class="p">)</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">fltB</span><span class="p">))</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            
          </td>
          <td class="code leading">
            
          <div class="highlight"><pre>    <span class="nx">strB</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">Marshal</span><span class="p">(</span><span class="s">&quot;gopher&quot;</span><span class="p">)</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">strB</span><span class="p">))</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            <p>这是一些切片和 map 编码成 JSON 数组和对象的例子。</p>

          </td>
          <td class="code leading">
            
          <div class="highlight"><pre>    <span class="nx">slcD</span> <span class="o">:=</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">&quot;apple&quot;</span><span class="p">,</span> <span class="s">&quot;peach&quot;</span><span class="p">,</span> <span class="s">&quot;pear&quot;</span><span class="p">}</span>
    <span class="nx">slcB</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">Marshal</span><span class="p">(</span><span class="nx">slcD</span><span class="p">)</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">slcB</span><span class="p">))</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            
          </td>
          <td class="code leading">
            
          <div class="highlight"><pre>    <span class="nx">mapD</span> <span class="o">:=</span> <span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="s">&quot;apple&quot;</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="s">&quot;lettuce&quot;</span><span class="p">:</span> <span class="mi">7</span><span class="p">}</span>
    <span class="nx">mapB</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">Marshal</span><span class="p">(</span><span class="nx">mapD</span><span class="p">)</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">mapB</span><span class="p">))</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            <p>JSON 包可以自动的编码你的自定义类型。
编码的输出只包含可导出的字段，并且默认使用字段名作为 JSON 数据的键名。</p>

          </td>
          <td class="code leading">
            
          <div class="highlight"><pre>    <span class="nx">res1D</span> <span class="o">:=</span> <span class="o">&amp;</span><span class="nx">response1</span><span class="p">{</span>
        <span class="nx">Page</span><span class="p">:</span>   <span class="mi">1</span><span class="p">,</span>
        <span class="nx">Fruits</span><span class="p">:</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">&quot;apple&quot;</span><span class="p">,</span> <span class="s">&quot;peach&quot;</span><span class="p">,</span> <span class="s">&quot;pear&quot;</span><span class="p">}}</span>
    <span class="nx">res1B</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">Marshal</span><span class="p">(</span><span class="nx">res1D</span><span class="p">)</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">res1B</span><span class="p">))</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            <p>你可以给结构字段声明标签来自定义编码的 JSON 数据的键名。
上面 <code>Response2</code> 的定义，就是这种标签的一个例子。</p>

          </td>
          <td class="code leading">
            
          <div class="highlight"><pre>    <span class="nx">res2D</span> <span class="o">:=</span> <span class="o">&amp;</span><span class="nx">response2</span><span class="p">{</span>
        <span class="nx">Page</span><span class="p">:</span>   <span class="mi">1</span><span class="p">,</span>
        <span class="nx">Fruits</span><span class="p">:</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">&quot;apple&quot;</span><span class="p">,</span> <span class="s">&quot;peach&quot;</span><span class="p">,</span> <span class="s">&quot;pear&quot;</span><span class="p">}}</span>
    <span class="nx">res2B</span><span class="p">,</span> <span class="nx">_</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">Marshal</span><span class="p">(</span><span class="nx">res2D</span><span class="p">)</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">res2B</span><span class="p">))</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            <p>现在来看看将  JSON 数据解码为 Go 值的过程。
这是一个普通数据结构的解码例子。</p>

          </td>
          <td class="code leading">
            
          <div class="highlight"><pre>    <span class="nx">byt</span> <span class="o">:=</span> <span class="p">[]</span><span class="nb">byte</span><span class="p">(</span><span class="s">`{&quot;num&quot;:6.13,&quot;strs&quot;:[&quot;a&quot;,&quot;b&quot;]}`</span><span class="p">)</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            <p>我们需要提供一个 JSON 包可以存放解码数据的变量。
这里的 <code>map[string]interface{}</code> 是一个键为 string，值为任意值的 map。</p>

          </td>
          <td class="code leading">
            
          <div class="highlight"><pre>    <span class="kd">var</span> <span class="nx">dat</span> <span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kd">interface</span><span class="p">{}</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            <p>这是实际的解码，以及相关错误的检查。</p>

          </td>
          <td class="code leading">
            
          <div class="highlight"><pre>    <span class="k">if</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">Unmarshal</span><span class="p">(</span><span class="nx">byt</span><span class="p">,</span> <span class="o">&amp;</span><span class="nx">dat</span><span class="p">);</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
        <span class="nb">panic</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
    <span class="p">}</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">dat</span><span class="p">)</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            <p>为了使用解码 map 中的值，我们需要将他们进行适当的类型转换。
例如，这里我们将 <code>num</code> 的值转换成 <code>float64</code> 类型。</p>

          </td>
          <td class="code leading">
            
          <div class="highlight"><pre>    <span class="nx">num</span> <span class="o">:=</span> <span class="nx">dat</span><span class="p">[</span><span class="s">&quot;num&quot;</span><span class="p">].(</span><span class="kt">float64</span><span class="p">)</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">num</span><span class="p">)</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            <p>访问嵌套的值需要一系列的转化。</p>

          </td>
          <td class="code leading">
            
          <div class="highlight"><pre>    <span class="nx">strs</span> <span class="o">:=</span> <span class="nx">dat</span><span class="p">[</span><span class="s">&quot;strs&quot;</span><span class="p">].([]</span><span class="kd">interface</span><span class="p">{})</span>
    <span class="nx">str1</span> <span class="o">:=</span> <span class="nx">strs</span><span class="p">[</span><span class="mi">0</span><span class="p">].(</span><span class="kt">string</span><span class="p">)</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">str1</span><span class="p">)</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            <p>我们还可以将 JSON 解码为自定义数据类型。
这样做的好处是，可以为我们的程序增加附加的类型安全性，
并在访问解码后的数据时不需要类型断言。</p>

          </td>
          <td class="code leading">
            
          <div class="highlight"><pre>    <span class="nx">str</span> <span class="o">:=</span> <span class="s">`{&quot;page&quot;: 1, &quot;fruits&quot;: [&quot;apple&quot;, &quot;peach&quot;]}`</span>
    <span class="nx">res</span> <span class="o">:=</span> <span class="nx">response2</span><span class="p">{}</span>
    <span class="nx">json</span><span class="p">.</span><span class="nx">Unmarshal</span><span class="p">([]</span><span class="nb">byte</span><span class="p">(</span><span class="nx">str</span><span class="p">),</span> <span class="o">&amp;</span><span class="nx">res</span><span class="p">)</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">res</span><span class="p">)</span>
    <span class="nx">fmt</span><span class="p">.</span><span class="nx">Println</span><span class="p">(</span><span class="nx">res</span><span class="p">.</span><span class="nx">Fruits</span><span class="p">[</span><span class="mi">0</span><span class="p">])</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            <p>在上面例子的标准输出上，
我们总是使用 byte和 string 作为数据和 JSON 表示形式之间的中介。
当然，我们也可以像 <code>os.Stdout</code> 一样直接将 JSON 编码流传输到
<code>os.Writer</code> 甚至 HTTP 响应体。</p>

          </td>
          <td class="code">
            
          <div class="highlight"><pre>    <span class="nx">enc</span> <span class="o">:=</span> <span class="nx">json</span><span class="p">.</span><span class="nx">NewEncoder</span><span class="p">(</span><span class="nx">os</span><span class="p">.</span><span class="nx">Stdout</span><span class="p">)</span>
    <span class="nx">d</span> <span class="o">:=</span> <span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">int</span><span class="p">{</span><span class="s">&quot;apple&quot;</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="s">&quot;lettuce&quot;</span><span class="p">:</span> <span class="mi">7</span><span class="p">}</span>
    <span class="nx">enc</span><span class="p">.</span><span class="nx">Encode</span><span class="p">(</span><span class="nx">d</span><span class="p">)</span>
<span class="p">}</span>
</pre></div>

          </td>
        </tr>
        
      </table>
      
      <table>
        
        <tr>
          <td class="docs">
            
          </td>
          <td class="code leading">
            
          <div class="highlight"><pre><span class="gp">$</span> go run json.go
<span class="go">true</span>
<span class="go">1</span>
<span class="go">2.34</span>
<span class="go">&quot;gopher&quot;</span>
<span class="go">[&quot;apple&quot;,&quot;peach&quot;,&quot;pear&quot;]</span>
<span class="go">{&quot;apple&quot;:5,&quot;lettuce&quot;:7}</span>
<span class="go">{&quot;Page&quot;:1,&quot;Fruits&quot;:[&quot;apple&quot;,&quot;peach&quot;,&quot;pear&quot;]}</span>
<span class="go">{&quot;page&quot;:1,&quot;fruits&quot;:[&quot;apple&quot;,&quot;peach&quot;,&quot;pear&quot;]}</span>
<span class="go">map[num:6.13 strs:[a b]]</span>
<span class="go">6.13</span>
<span class="go">a</span>
<span class="go">{1 [apple peach]}</span>
<span class="go">apple</span>
<span class="go">{&quot;apple&quot;:5,&quot;lettuce&quot;:7}</span>
</pre></div>

          </td>
        </tr>
        
        <tr>
          <td class="docs">
            <p>至此，我们已经学习了基本的 Go JSON 知识，如果想要获取更多的信息，
请查阅 <a href="http://blog.golang.org/2011/01/json-and-go.html">JSON and Go</a> 博文
和 <a href="http://golang.org/pkg/encoding/json/">JSON package docs</a>。</p>

          </td>
          <td class="code empty">
            
          
          </td>
        </tr>
        
      </table>
      
      
      <p class="next">
        下一个例子: <a href="xml">XML</a>
      </p>
      
      <p class="footer">
        <a href="https://twitter.com/mmcgrana">@mmcgrana</a> 编写 | <a href="https://github.com/gobyexample-cn">gobyexample-cn</a> 翻译 | <a href="https://github.com/gobyexample-cn/gobyexample/issues">反馈</a> | <a href="https://github.com/gobyexample-cn/gobyexample">源码</a> | <a href="https://github.com/mmcgrana/gobyexample#license">license</a>      </p>
      </p>
    </div>
    <script>
      var codeLines = [];
      codeLines.push('');codeLines.push('package main\u000A');codeLines.push('import (\u000A    \"encoding/json\"\u000A    \"fmt\"\u000A    \"os\"\u000A)\u000A');codeLines.push('type response1 struct {\u000A    Page   int\u000A    Fruits []string\u000A}\u000A');codeLines.push('type response2 struct {\u000A    Page   int      `json:\"page\"`\u000A    Fruits []string `json:\"fruits\"`\u000A}\u000A');codeLines.push('func main() {\u000A');codeLines.push('    bolB, _ := json.Marshal(true)\u000A    fmt.Println(string(bolB))\u000A');codeLines.push('    intB, _ := json.Marshal(1)\u000A    fmt.Println(string(intB))\u000A');codeLines.push('    fltB, _ := json.Marshal(2.34)\u000A    fmt.Println(string(fltB))\u000A');codeLines.push('    strB, _ := json.Marshal(\"gopher\")\u000A    fmt.Println(string(strB))\u000A');codeLines.push('    slcD := []string{\"apple\", \"peach\", \"pear\"}\u000A    slcB, _ := json.Marshal(slcD)\u000A    fmt.Println(string(slcB))\u000A');codeLines.push('    mapD := map[string]int{\"apple\": 5, \"lettuce\": 7}\u000A    mapB, _ := json.Marshal(mapD)\u000A    fmt.Println(string(mapB))\u000A');codeLines.push('    res1D := &response1{\u000A        Page:   1,\u000A        Fruits: []string{\"apple\", \"peach\", \"pear\"}}\u000A    res1B, _ := json.Marshal(res1D)\u000A    fmt.Println(string(res1B))\u000A');codeLines.push('    res2D := &response2{\u000A        Page:   1,\u000A        Fruits: []string{\"apple\", \"peach\", \"pear\"}}\u000A    res2B, _ := json.Marshal(res2D)\u000A    fmt.Println(string(res2B))\u000A');codeLines.push('    byt := []byte(`{\"num\":6.13,\"strs\":[\"a\",\"b\"]}`)\u000A');codeLines.push('    var dat map[string]interface{}\u000A');codeLines.push('    if err := json.Unmarshal(byt, &dat); err != nil {\u000A        panic(err)\u000A    }\u000A    fmt.Println(dat)\u000A');codeLines.push('    num := dat[\"num\"].(float64)\u000A    fmt.Println(num)\u000A');codeLines.push('    strs := dat[\"strs\"].([]interface{})\u000A    str1 := strs[0].(string)\u000A    fmt.Println(str1)\u000A');codeLines.push('    str := `{\"page\": 1, \"fruits\": [\"apple\", \"peach\"]}`\u000A    res := response2{}\u000A    json.Unmarshal([]byte(str), &res)\u000A    fmt.Println(res)\u000A    fmt.Println(res.Fruits[0])\u000A');codeLines.push('    enc := json.NewEncoder(os.Stdout)\u000A    d := map[string]int{\"apple\": 5, \"lettuce\": 7}\u000A    enc.Encode(d)\u000A}\u000A');codeLines.push('');codeLines.push('');
    </script>
    <script src="site.js" async></script>
  </body>
</html>
